﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml.Linq;
//using System.Threading;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Reflection;
using FBEntities;
using System.Threading;
using XFControls;

namespace XDAFacebook
{
    public partial class LoginCustom : Form
    {
        private string settingsFileName = "\\XDAFacebookSettings.xml";
        private string debugFileName = "\\XDAFacebookDebug.xml";
        private string loginCustomLocation = "\\Resources\\login_screen.png";
        private XDocument settings = null;
        private Authentication auth;

        /// <summary>
        /// Initializes a new instance of the <see cref="LoginCustom"/> class.
        /// </summary>
        public LoginCustom()
        {
            InitializeComponent();
            string location = GetCurrent_Directory() + loginCustomLocation;

            try
            {
                var img = new Bitmap(location);
                pbMainBackground.Image = img;
            }
            catch (Exception e) { }

            settingsFileName = GetCurrent_Directory() + settingsFileName;
            debugFileName = GetCurrent_Directory() + debugFileName;
        }

        public static string GetCurrent_Directory()
        {
            return Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
        }


        /// <summary>
        /// Loads the app settings.
        /// </summary>
        private void loadSettings()
        {
            if (File.Exists(settingsFileName))
            {
                settings = XDocument.Load(settingsFileName);
                tbPassword.Focus();

                if (settings.Root.Descendants("email").Any())
                    tbUserName.Text = settings.Root.Element("email").Value;
                else
                    settings.Root.Add(new XElement("email"));

                if (settings.Root.Descendants("auth_key").Any())
                    auth = new Authentication(settings.Root.Element("auth_key").Value.Decrypt());
                else
                {
                    auth = new Authentication();
                    settings.Root.Add(new XElement("auth_key"));
                }

                ipKeyboard.Enabled = true;
            }
            else
                settings = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    new XElement("settings",
                        new XElement("email"),
                        new XElement("auth_key")));

        }

        /// <summary>
        /// Handles the Click event of the btLogin control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btLogin_Click(object sender, EventArgs e)
        {
            settings.Root.Element("email").SetValue(tbUserName.Text);
            settings.Save(settingsFileName);


            // The auth variable will do all the authenticating.
            auth = new Authentication(tbUserName.Text, tbPassword.Text);
            auth.ipKeyBoard = ipKeyboard;   // Needed so auth can raise and lower keyboard

            try
            {
                // This is where the app starts once the user gets logged in.
                WaitCallback cb = new WaitCallback(authenticate);
                ThreadPool.QueueUserWorkItem(cb);

            }
            catch (Exception ex)
            {
                AddDebugInfo("Location 1: " + ex.Message + "\n" + ex.StackTrace + "\n" + ex.InnerException.ToString(), "error");
                MessageBox.Show("An error occurred and info was saved to " + debugFileName + ".  Please PM this file to the XDA-Developer");
            }
            this.xfLoginButton.Enabled = false;
            ipKeyboard.Enabled = false;
            this.xfLoginButton.Focus();
        }

        /// <summary>
        /// Authenticates the user.  This method is ran on a background thread.
        /// </summary>
        /// <param name="val">The val.</param>
        private void authenticate(object val)
        {
            switch (auth.Authenticate())
            {
                case AuthenticationReturn.BadLogin:
                    MessageBox.Show("Incorrect Email or Password");     // Or could be another error
                    break;
                case AuthenticationReturn.Success:
                    //Sucess!  Now start doing stuff
                    FBDataSource me = new FBDataSource(auth.AuthKey);
                    XFItemControlUtils.Me = me;

                    this.pbMainBackground.Invoke(new EventHandler(closeForm));
                    return;
                case AuthenticationReturn.TimeOut:
                    MessageBox.Show("There was a server Timeout.  make sure you have an internet connection");     // Or could be another error
                    break;
                case AuthenticationReturn.Unknown:
                    MessageBox.Show("There was an unknown error");     // Or could be another error
                    break;
            }

            this.xfLoginButton.Invoke(new EventHandler(changeLoginButton));
        }

        public void AddDebugInfo(string message, string type)
        {
            XDocument db = null;
            if (File.Exists(debugFileName))
            {
                db = XDocument.Load(debugFileName);
            }
            else
                db = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    new XElement("debug"));

            db.Root.Add(new XElement("message",
                new XAttribute("type", type),
                new XAttribute("date", DateTime.Now.ToString()), message));

            db.Save(debugFileName);
        }

        /// <summary>
        /// Changes the login button.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void changeLoginButton(object sender, EventArgs e)
        {
            this.xfLoginButton.ResetButton();
            this.xfLoginButton.Enabled = true;
        }

        /// <summary>
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void closeForm(object sender, EventArgs e)
        {
            Main main = new Main();
            main.Show();

            this.Close();
        }

        /// <summary>
        /// Handles the Load event of the LoginCustom control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void LoginCustom_Load(object sender, EventArgs e)
        {
            loadSettings();
        }

        /// <summary>
        /// Handles the Closing event of the LoginCustom control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        private void LoginCustom_Closing(object sender, CancelEventArgs e)
        {
            if (this.xfCheckBox.Checked == true)
            {
                if (auth != null && !string.IsNullOrEmpty(auth.AuthKey) && tbUserName.Text != null)
                {
                    settings.Root.Element("auth_key").SetValue(auth.AuthKey.Encrypt());
                    settings.Root.Element("email").SetValue(tbUserName.Text);
                    settings.Save(settingsFileName);
                }
            }
            else
            {
                if (File.Exists(settingsFileName))
                    File.Delete(settingsFileName);
            }
        }

        private void miExit_Click(object sender, EventArgs e)
        {
            this.Close();
            Application.Exit();
        }

        private void miAbout_Click(object sender, EventArgs e)
        {
            About About = new About();
            About.Show();
        }

        private void tbUserName_GotFocus(object sender, EventArgs e)
        {
            ipKeyboard.Enabled = true;
        }

        private void tbPassword_GotFocus(object sender, EventArgs e)
        {
            ipKeyboard.Enabled = true;
            tbPassword.SelectAll();
        }
    }
}